package org.zzz.hepotaiya.config;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.zzz.hepotaiya.exception.ParseException;
import org.zzz.hepotaiya.util.ResourceUtil;

public class XMLConfigParser implements ConfigParser {

	public List<BatchConfig> parse() throws ParseException {
		List<BatchConfig> ret = new ArrayList<BatchConfig>();
		File file = new File(path);
		try {
			Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
			XPath xpath = XPathFactory.newInstance().newXPath();
			NodeList batchList = (NodeList)xpath.evaluate("//batchy/batch/@name", document, XPathConstants.NODESET);
			for (int i = 0; i < batchList.getLength(); i++) {
				BatchConfig config = new BatchConfig();
				config.batchName = batchList.item(i).getNodeValue();
				if (StringUtils.isEmpty(config.batchName)) {
					throw new ParseException(ResourceUtil.getString("config.parser.nullname", (Object[])null));
				}
				String baseexp = "//batchy/batch[@name='" + config.batchName + "']";
				String phase = (String)xpath.evaluate(baseexp+"/phase", document, XPathConstants.STRING);
				if (NumberUtils.isNumber(phase)) {
					config.phase = NumberUtils.toInt(phase);
				}
				String index = (String)xpath.evaluate(baseexp+"/index", document, XPathConstants.STRING);
				if (NumberUtils.isNumber(index)) {
					config.index = NumberUtils.toInt(index);
				}
				String isErrorStop = (String)xpath.evaluate(baseexp+"/isErrorStop", document, XPathConstants.STRING);
				if (BooleanUtils.toBoolean(isErrorStop)) {
					config.isErrorStop = BooleanUtils.toBoolean(isErrorStop);
				}
				Map<String, Boolean> map = new HashMap<String, Boolean>();
				String failText= (String)xpath.evaluate(baseexp+"/depency/fail", document, XPathConstants.STRING);
				String[] fail = StringUtils.split(failText, ",");
				for (String string : fail) {
					map.put(string, false);
				}
				String successText= (String)xpath.evaluate(baseexp+"/depency/success", document, XPathConstants.STRING);
				String[] success = StringUtils.split(successText, ",");
				for (String string : success) {
					map.put(string, true);
				}
				if (map.size() != 0) {
					config.depencyMap = map;
				}
				ret.add(config);
			}
		} catch (Exception e) {
			throw new ParseException(e);
		}
		return ret;
	}
	
	String path;
	public void setConfigFilePath(String string) {
		this.path = string;
	}
}
